home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / src / tparam.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-25  |  7.1 KB  |  291 lines

  1. /* Merge parameters into a termcap entry string.
  2.    Copyright (C) 1985, 1987, 1992, 1993, 1994 Free Software Foundation, Inc.
  3.  
  4. This file is part of XEmacs.
  5.  
  6. XEmacs is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by the
  8. Free Software Foundation; either version 2, or (at your option) any
  9. later version.
  10.  
  11. XEmacs is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14. for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with XEmacs; see the file COPYING.  If not, write to the Free
  18. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Synched up with: Not synched with FSF. */
  21.  
  22. /* config.h may rename various library functions such as malloc.  */
  23. #ifdef emacs
  24.  
  25. #include <config.h>
  26.  
  27. #include <string.h>
  28.  
  29. #define realloc xrealloc
  30. #define malloc xmalloc
  31. #define free xfree
  32. extern void *xmalloc (int size);
  33. extern void *xrealloc (void *, int size);
  34.  
  35. #else /* emacs */
  36.  
  37. #ifdef STDC_HEADERS
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #else
  41. extern char *malloc ();
  42. extern char *realloc ();
  43. #endif
  44.  
  45. #endif /* !emacs */
  46.  
  47. /* Assuming STRING is the value of a termcap string entry
  48.    containing `%' constructs to expand parameters,
  49.    merge in parameter values and store result in block OUTSTRING points to.
  50.    LEN is the length of OUTSTRING.  If more space is needed,
  51.    a block is allocated with `malloc'.
  52.  
  53.    The value returned is the address of the resulting string.
  54.    This may be OUTSTRING or may be the address of a block got with `malloc'.
  55.    In the latter case, the caller must free the block.
  56.  
  57.    The fourth and following args to tparam serve as the parameter values.  */
  58.  
  59. static char *tparam1 (CONST char *string, char *outstring, int len,
  60.                       CONST char *up, CONST char *left, 
  61.                       int *argp);
  62.  
  63. char *tparam (CONST char *string, char *outstring, int len, int arg0, int arg1,
  64.           int arg2, int arg3);
  65. char *
  66. tparam (CONST char *string, char *outstring, int len, int arg0, int arg1,
  67.     int arg2, int arg3)
  68. {
  69.   int arg[4];
  70.   arg[0] = arg0;
  71.   arg[1] = arg1;
  72.   arg[2] = arg2;
  73.   arg[3] = arg3;
  74.   return tparam1 (string, outstring, len, 0, 0, arg);
  75. }
  76.  
  77. CONST char *BC;
  78. CONST char *UP;
  79.  
  80. static char tgoto_buf[50];
  81.  
  82. char *tgoto (CONST char *cm, int hpos, int vpos);
  83. char *
  84. tgoto (CONST char *cm, int hpos, int vpos)
  85. {
  86.   int args[2];
  87.   if (!cm)
  88.     return 0;
  89.   args[0] = vpos;
  90.   args[1] = hpos;
  91.   return tparam1 (cm, tgoto_buf, 50, UP, BC, args);
  92. }
  93.  
  94. static char *
  95. tparam1 (CONST char *string, char *outstring, int len, CONST char *up,
  96.      CONST char *left, int *argp)
  97. {
  98.   int c;
  99.   CONST char *p = string;
  100.   char *op = outstring;
  101.   char *outend;
  102.   int outlen = 0;
  103.  
  104.   int tem;
  105.   int *old_argp = argp;
  106.   int doleft = 0;
  107.   int doup = 0;
  108.  
  109.   outend = outstring + len;
  110.  
  111.   while (1)
  112.     {
  113.       /* If the buffer might be too short, make it bigger.  */
  114.       if (op + 5 >= outend)
  115.     {
  116.       char *new;
  117.       if (outlen == 0)
  118.         {
  119.           outlen = len + 40;
  120.           new = (char *) malloc (outlen);
  121.           outend += 40;
  122.           memcpy (new, outstring, op - outstring);
  123.         }
  124.       else
  125.         {
  126.           outend += outlen;
  127.           outlen *= 2;
  128.           new = (char *) realloc (outstring, outlen);
  129.         }
  130.       op += new - outstring;
  131.       outend += new - outstring;
  132.       outstring = new;
  133.     }
  134.       c = *p++;
  135.       if (!c)
  136.     break;
  137.       if (c == '%')
  138.     {
  139.       c = *p++;
  140.       tem = *argp;
  141.       switch (c)
  142.         {
  143.         case 'd':        /* %d means output in decimal.  */
  144.           if (tem < 10)
  145.         goto onedigit;
  146.           if (tem < 100)
  147.         goto twodigit;
  148.         case '3':        /* %3 means output in decimal, 3 digits.  */
  149.           if (tem > 999)
  150.         {
  151.           *op++ = tem / 1000 + '0';
  152.           tem %= 1000;
  153.         }
  154.           *op++ = tem / 100 + '0';
  155.         case '2':        /* %2 means output in decimal, 2 digits.  */
  156.         twodigit:
  157.           tem %= 100;
  158.           *op++ = tem / 10 + '0';
  159.         onedigit:
  160.           *op++ = tem % 10 + '0';
  161.           argp++;
  162.           break;
  163.  
  164.         case 'C':
  165.           /* For c-100: print quotient of value by 96, if nonzero,
  166.          then do like %+.  */
  167.           if (tem >= 96)
  168.         {
  169.           *op++ = tem / 96;
  170.           tem %= 96;
  171.         }
  172.         case '+':        /* %+x means add character code of char x.  */
  173.           tem += *p++;
  174.         case '.':        /* %. means output as character.  */
  175.           if (left)
  176.         {
  177.           /* If want to forbid output of 0 and \n and \t,
  178.              and this is one of them, increment it.  */
  179.           while (tem == 0 || tem == '\n' || tem == '\t')
  180.             {
  181.               tem++;
  182.               if (argp == old_argp)
  183.             doup++, outend -= strlen (up);
  184.               else
  185.             doleft++, outend -= strlen (left);
  186.             }
  187.         }
  188.           *op++ = tem | 0200;
  189.         case 'f':        /* %f means discard next arg.  */
  190.           argp++;
  191.           break;
  192.  
  193.         case 'b':        /* %b means back up one arg (and re-use it). */
  194.           argp--;
  195.           break;
  196.  
  197.         case 'r':        /* %r means interchange following two args. */
  198.           argp[0] = argp[1];
  199.           argp[1] = tem;
  200.           old_argp++;
  201.           break;
  202.  
  203.         case '>':        /* %>xy means if arg is > char code of x, */
  204.           if (argp[0] > *p++) /* then add char code of y to the arg, */
  205.         argp[0] += *p;    /* and in any case don't output. */
  206.           p++;        /* Leave the arg to be output later. */
  207.           break;
  208.  
  209.         case 'a':        /* %a means arithmetic. */
  210.           /* Next character says what operation.
  211.          Add or subtract either a constant or some other arg. */
  212.           /* First following character is + to add or - to subtract
  213.          or = to assign.  */
  214.           /* Next following char is 'p' and an arg spec
  215.          (0100 plus position of that arg relative to this one)
  216.          or 'c' and a constant stored in a character. */
  217.           tem = p[2] & 0177;
  218.           if (p[1] == 'p')
  219.         tem = argp[tem - 0100];
  220.           if (p[0] == '-')
  221.         argp[0] -= tem;
  222.           else if (p[0] == '+')
  223.         argp[0] += tem;
  224.           else if (p[0] == '*')
  225.         argp[0] *= tem;
  226.           else if (p[0] == '/')
  227.         argp[0] /= tem;
  228.           else
  229.         argp[0] = tem;
  230.  
  231.           p += 3;
  232.           break;
  233.  
  234.         case 'i':        /* %i means add one to arg, */
  235.           argp[0] ++;    /* and leave it to be output later. */
  236.           argp[1] ++;    /* Increment the following arg, too!  */
  237.           break;
  238.  
  239.         case '%':        /* %% means output %; no arg. */
  240.           goto ordinary;
  241.  
  242.         case 'n':        /* %n means xor each of next two args with 140. */
  243.           argp[0] ^= 0140;
  244.           argp[1] ^= 0140;
  245.           break;
  246.  
  247.         case 'm':        /* %m means xor each of next two args with 177. */
  248.           argp[0] ^= 0177;
  249.           argp[1] ^= 0177;
  250.           break;
  251.  
  252.         case 'B':        /* %B means express arg as BCD char code. */
  253.           argp[0] += 6 * (tem / 10);
  254.           break;
  255.  
  256.         case 'D':        /* %D means weird Delta Data transformation. */
  257.           argp[0] -= 2 * (tem % 16);
  258.           break;
  259.         }
  260.     }
  261.       else
  262.     /* Ordinary character in the argument string.  */
  263.       ordinary:
  264.     *op++ = c;
  265.     }
  266.   *op = 0;
  267.   while (doup-- > 0)
  268.     strcat (op, up);
  269.   while (doleft-- > 0)
  270.     strcat (op, left);
  271.   return outstring;
  272. }
  273.  
  274. #ifdef DEBUG
  275.  
  276. main (argc, argv)
  277.      int argc;
  278.      char **argv;
  279. {
  280.   char buf[50];
  281.   int args[3];
  282.   args[0] = atoi (argv[2]);
  283.   args[1] = atoi (argv[3]);
  284.   args[2] = atoi (argv[4]);
  285.   tparam1 (argv[1], buf, "LEFT", "UP", args);
  286.   printf ("%s\n", buf);
  287.   return 0;
  288. }
  289.  
  290. #endif /* DEBUG */
  291.